import { Injectable, NestMiddleware } from '@nestjs/common'
import { Request, Response, NextFunction } from 'express'
import { VisitService } from '../visit/visit.service'
import IP2Region from 'ip2region'
import { CreateVisitDto } from 'src/visit/dto/create-visit.dto'

@Injectable()
export class IPMiddleware implements NestMiddleware {
    constructor(private readonly visitService: VisitService) { }

    async use(req: Request, res: Response, next: NextFunction) {
        const ua = req.headers['user-agent']
        const isBaiduSpider = /Baiduspider/i.test(ua)
        const isGooglebot = /Googlebot/i.test(ua)
        const isBingbot = /bingbot/i.test(ua)
        const is360Spider = /360Spider/i.test(ua)
        if (isBaiduSpider || isGooglebot || isBingbot || is360Spider) {
            next()
        } else {
            let realIP = req.headers['x-real-ip'] || req.ip
            if (realIP instanceof Array) { realIP = realIP[0] }
            if (realIP === '::1' || realIP === '::ffff:127.0.0.1') {        
                next()
            } else {
                const ipQuery = new IP2Region()
                const ipAddress = ipQuery.search(realIP)
                const createVisitDto: CreateVisitDto = new CreateVisitDto()
                createVisitDto.ip = realIP
                createVisitDto.country = ipAddress.country
                createVisitDto.province = ipAddress.province
                createVisitDto.city = ipAddress.city
                await this.visitService.upsert(realIP, createVisitDto)
                next()
            }
        }
    }
}